#include <iostream>

namespace bga
{

template< typename T >
Vector2<T>::Vector2()
{
}

template< typename T >
Vector2<T>::Vector2(T x, T y)
{
    this->arrayValues[0] = x;
    this->arrayValues[1] = y;
}

template< typename T >
Vector2<T>::Vector2(const Vector2<T>& vector)
{
    this->arrayValues[0] = vector.getX();
    this->arrayValues[1] = vector.getY();
}

template< typename T >
Vector2<T>::~Vector2()
{

}

template< typename T >
T Vector2<T>::getX() const
{
    return this->arrayValues[0];
}

template< typename T >
T Vector2<T>::getY() const
{
    return this->arrayValues[1];
}


template< typename T >
void Vector2<T>::setX(T X)
{
    this->arrayValues[0] = X;
}

template< typename T >
void Vector2<T>::setY(T Y)
{
    this->arrayValues[1] = Y;
}

template< typename T >
void Vector2<T>::setXY(T X, T Y)
{
    this->arrayValues[0] = X;
    this->arrayValues[1] = Y;
}

template< typename T >
double Vector2<T>::getNorm() const
{
    return sqrt( this->getX() * this->getX() + this->getY() * this->getY() );
}

template< typename T >
void Vector2<T>::normalize()
{
    double norme = this->norme();
    this->arrayValues[0] /= norme;
    this->arrayValues[1] /= norme;
}

template< typename T >
Vector2<T> Vector2<T>::normalize(const Vector2<T>& aNormer)
{
    Vector2<T> vector(aNormer);
    vector.normalize();
    return vector;
}

template< typename T >
Vector2<T> Vector2<T>::operator+(const Vector2<T> &V) const
{
    return Vector3d(this->getX() + V.getX(),
                    this->getY() + V.getY());
}

template< typename T >
Vector2<T>& Vector2<T>::operator+=(const Vector2<T> &V)
{
    this->setX(this->getX() + V.getX());
    this->setY(this->getY() + V.getY());
    return *this;
}

template< typename T >
Vector2<T> Vector2<T>::operator-(const Vector2<T> &V) const
{
    return Vector2<T>(this->getX() - V.getX(),
                    this->getY() - V.getY());
}

template< typename T >
Vector2<T>& Vector2<T>::operator-=(const Vector2<T> &V)
{
    this->setX(this->getX() - V.getX());
    this->setY(this->getY() - V.getY());
    return *this;
}

template< typename T >
template< typename U >
Vector2<T> Vector2<T>::operator*(U value) const
{
    return Vector3d(this->getX() * value,
                    this->getY() * value);
}

template< typename T >
double Vector2<T>::operator*(const Vector2<T>& v) const
{
    return (this->getX() * v.getX() +
                    this->getY() * v.getY());
}

template< typename T >
Vector2<T>& Vector2<T>::operator=(const Vector2<T>& v)
{
    this->arrayValues[0] = v.getX();
    this->arrayValues[1] = v.getY();
    return *this;
}

template< typename T>
std::ostream& operator<< (std::ostream& stream, const Vector2<T>& V)
{
    stream << V.getX() << "   " << V.getY() ;
    return stream;
}

}
